package cn.com.openportal.ffw.common.aspect;

import cn.com.openportal.ffw.common.exception.RRException;
import cn.com.openportal.ffw.common.utils.*;
import cn.com.openportal.ffw.modules.sys.entity.SysUserEntity;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * 数据过滤，切面处理类
 *
 * @author LeeSon
 */
@Aspect
@Component
public class DataFilterNativeAspect {
    private static Logger logger = LoggerFactory.getLogger(DataFilterNativeAspect.class);

    @Autowired
    private SQLFilterNativeUtils SQLFilterNativeUtils;

    @Pointcut("@annotation(cn.com.openportal.ffw.common.annotation.DataFilterNative)")
    public void dataFilterCut() {
    }

    @Around("dataFilterCut()")
    public Object dataFilter(ProceedingJoinPoint point) throws Throwable {
        SysUserEntity user = ShiroUtils.getUserEntity();
        //如果不是超级管理员，则进行数据过滤
        if (user.getUserId() != Constant.SUPER_ADMIN) {
            //数据处理
            if (doDataFilter(user, point)) {
                return point.proceed();
            }
            return null;
        }
        return point.proceed();
    }

    private boolean doDataFilter(SysUserEntity user, JoinPoint point) throws Exception {
        try {
            return chooseMethod(user, point);
        } catch (RRException e) {
            logger.error(e.getMessage());
            throw new RRException("操作筛查处理完成", 0);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new RRException("发生错误，请联系管理员");
        } catch (Throwable throwable) {
            logger.error(throwable.getMessage(), throwable.getMessage());
            throw new RRException("发生错误，请联系管理员");
        }
    }

    private boolean chooseMethod(SysUserEntity user, JoinPoint point) throws Exception {
        MethodSignature signature = (MethodSignature) point.getSignature();
        String methodName = signature.getName();
        Object[] params = point.getArgs();

        if (methodName.equals("page") || methodName.equals("deleteQuery")) {
            //BaseQueryNative query
            Object obj = params[0];
            if (obj != null && BaseQueryNative.class.getName().equals(obj.getClass().getSuperclass().getName())) {
                SQLFilterNativeUtils.doDataFilter(user, point, obj);
                return true;
            }
            throw new Exception("methodName: " + methodName + " Param Error : " + obj.getClass().getName());
        } else if (methodName.equals("updateMate") || methodName.equals("update")) {
            //Entity entity
            Object obj = params[0];
            SQLFilterNativeUtils.isCanSQLtoUpdate(user, point, obj);
            return true;
        } else if (methodName.equals("info") || methodName.equals("delete")) {
            //Long id
            Object obj = params[0];
            SQLFilterNativeUtils.isCanSQLtoID(user, point, obj);
            return true;
        } else if (methodName.equals("deletes") || methodName.equals("deletesJSON")) {
            //Long[] ids
            Object obj = params[0];
            SQLFilterNativeUtils.isCanSQLtoIDS(user, point, obj);
            return true;
        } else if (methodName.equals("deleteAll")) {
            SQLFilterNativeUtils.doSQLtoDeleteAll(user, point);
            return false;
        }
        return false;
    }
}
